import networkx as nx
from utils.read_graph import read_graph
import re
from configparser import ConfigParser


class RewireGraph:
    def __init__(self, table_name):
        self.__index = None
        self.__start_node = None
        self.__table_name = table_name
        self.__keywords = None
        self.__error_type = None
        self.__graph = read_graph()
        self.__is_correct = self.__check_graph()

    def __get_key_words(self, row_string):
        return row_string.strip('\n').strip('\t').strip('_').split('_')

    def __check_if_stop(self, G, start_node):
        next_nodes = [i for i in G.neighbors(start_node)]
        for next_node in next_nodes:
            if 'STOP' in G.edges[start_node, next_node]['names']:
                return True
        return False

    def __check_regex(self, name, res):
        ll = re.findall(name.strip('REGEX'), res, flags=0)
        return len(ll) != 0

    # 字符串匹配的三种情况
    # 第一种 有一个字符子串完全没有匹配到 失败
    # 第二种 字符串没有匹配到图的终点 失败
    # 第三种 字符串完全匹配并走到终点 成功

    def __check_graph(self):
        row_string = self.__table_name
        G = self.__graph
        key_words = self.__get_key_words(row_string)
        self.__keywords = key_words
        start_node = 0
        index = 0
        if_find = False
        while index < len(key_words):
            if_find = False
            next_nodes = [i for i in G.neighbors(start_node)]
            for next_node in next_nodes:
                flag = 0
                for name in G.edges[start_node, next_node]['names']:
                    if key_words[index] == name or 'REGEX' in name and self.__check_regex(name, key_words[index]):
                        start_node = next_node
                        if_find = True
                        flag = 1
                        break
                if flag:
                    break
            if not if_find and index < len(key_words):
                self.__start_node = start_node
                self.__index = index
                return False
            index += 1
        if not self.__check_if_stop(G, start_node):
            self.__start_node = start_node
            return False
        return index == len(key_words) and if_find and self.__check_if_stop(G, start_node)

    def __get_neighbor_names(self, start_node):
        next_nodes = [i for i in self.__graph.neighbors(start_node)]
        res = []
        for next_node in next_nodes:
            for name in self.__graph.edges[start_node, next_node]['names']:
                res.append(name)
        return res

    def is_correct(self):
        return {"is_correct": self.__is_correct, "index": self.__index, "error_type": self.__error_type}

    def rewire(self):
        config = ConfigParser()
        config.read('./master/settings', encoding='utf-8')
        if config['name_type']['type'] == '1':
            file = open('./dfa/table_dfa_graph', 'a+')
        elif config['name_type']['type'] == '2':
            file = open('./dfa/index_dfa_graph', 'a+')
        # 第一种 有一个字符子串完全没有匹配到 失败
        if not self.__is_correct and self.__start_node != None and self.__index != None:

            # self.__index 当前存在问题的单词的下标
            # self.__start_node 当前所在位置的节点

            error_index = self.__index
            pre_node = self.__start_node
            next_node = self.__start_node
            print('*' * 20)
            print('Graph Rewiring: ')
            while error_index < len(self.__keywords):
                next_node = next_node + 10
                node_list = self.__graph.nodes()
                while next_node in node_list:
                    next_node += 1
                self.__graph.add_node(next_node)
                if error_index == (len(self.__keywords) - 1) and len(
                        re.findall(r"""[[p|f]?[1-9][0-9]*[d|w|m|y]|[p|f][1-9][0-9]*t[1-9][0-9]*[d|w|m|y]]""",
                                   self.__keywords[error_index],
                                   flags=0)) != 0:
                    next_node = 9999
                    # self.__graph.add_edge(pre_node, next_node, names=["[[p|f]?[1-9][0-9]*[d|w|m|y]|[p|f][1-9][0-9]*t[1-9]["
                    #                                              "0-9]*[d|w|m|y]]REGEX"])

                    file.write(str(pre_node) + ' ' + str(
                        next_node) + ' ' + r"""[[p|f]?[1-9][0-9]*[d|w|m|y]|[p|f][1-9][0-9]*t[1-9][0-9]*[d|w|m|y]]REGEX""" + '\n')
                else:
                    # self.__graph.add_edge(pre_node, next_node, names=[self.__keywords[error_index]])
                    file.write(str(pre_node) + ' ' + str(next_node) + ' ' + self.__keywords[error_index] + '\n')

                print('word ' + self.__keywords[error_index] + ' successfully added')
                error_index += 1
                pre_node = next_node

            print('*' * 20)
            if next_node != 9999:
                # self.__graph.add_edge(next_node, 10000, names=['STOP'])
                file.write(str(next_node) + ' ' + str(10000) + ' ' + 'STOP' + '\n')

        # 第二种 字符串没有匹配到图的终点 失败
        elif not self.__is_correct and self.__start_node != None:
            print('*' * 20)
            print('Graph Rewiring: ')
            print('a new road from ' + str(self.__start_node) + ' to the end has been successfully added')
            # self.__graph.add_edge(self.__start_node, 10000, names=['STOP'])
            file.write(str(self.__start_node) + ' ' + str(10000) + ' ' + 'STOP' + '\n')
            print('*' * 20)

        else:
            print('*' * 20)
            print('Successfully Matched, you do not need rewire')
            print('*' * 20)
